var Amqp = require('../amqp').Amqp;

/**
 * Work with exchanges.
 * Exchanges match and distribute messages across queues. Exchanges can be configured in the server
 * or created at runtime.
 *
 * @class
 * @extends events.EventEmitter
 * @exports Exchange as impl.Exchange
 * @param handler
 */
function Exchange(/**handlers.Channel*/handler){
    var exchange = this;
    this.handler = handler;
    /**
     * Confirms an exchange declaration.
     *
     * @name Exchange#declare
     * @event
     */
    handler.addListener('Amqp.Exchange.DeclareOk', function(frame){
        exchange.emit('declare', frame.method.arguments);
    });
    /**
     * Confirm deletion of an exchange.
     *
     * @name Exchange#delete
     * @event
     * @see api.Exchange#event:deleteOk
     */
    handler.addListener('Amqp.Exchange.DeleteOk', function(frame){
        exchange.emit('delete', frame.method.arguments);
    });
}
require('sys').inherits(Exchange, require('events').EventEmitter);
/**
 * Declare exchange, create if needed.
 *
 * This method creates an exchange if it does not already exist, and if the exchange exists,
 * verifies that it is of the correct and expected class.
 *
 * @param ticket An access ticket granted by the server for a certain set of access rights within a
 *      specific realm. Access tickets are valid within the channel where they were created, and
 *      expire when the channel closes.
 * @param exchange The exchange name is a client-selected string that identifies the exchange for
 *      publish methods. Exchange names may consist of any mixture of digits, letters, and
 *      underscores. Exchange names are scoped by the virtual host.
 * @param type Each exchange belongs to one of a set of exchange types implemented by the server.
 *      The exchange types define the functionality of the exchange - i.e. how messages are routed
 *      through it. It is not valid or meaningful to attempt to change the type of an existing
 *      exchange.
 * @param passive If <code>true</code>, the server will not create the exchange. The client can use
 *      this to check whether an exchange exists without modifying the server state.
 * @param durable If <code>true</code> when creating a new exchange, the exchange will be marked as
 *      durable. Durable exchanges remain active when a server restarts. Non-durable exchanges
 *      (transient exchanges) are purged if/when a server restarts.
 * @param autoDelete If <code>true</code>, the exchange is deleted when all queues have finished
 *      using it.
 * @param internal If <code>true</code>, the exchange may not be used directly by publishers, but
 *      only when bound to other exchanges. Internal exchanges are used to construct wiring that is
 *      not visible to applications.
 * @param nowait If <code>true</code>, the server will not respond to the method. The client should
 *      not wait for a reply method. If the server could not complete the method it will raise a
 *      channel or connection exception.
 * @param arguments A set of arguments for the declaration. The syntax and semantics of these
 *      arguments depends on the server implementation. This field is ignored if passive is
 *      <code>true</code>.
 */
Exchange.prototype.declare = function(/**Number*/ticket, /**String*/exchange, /**String*/type,
        /**Boolean*/passive, /**Boolean*/durable, /**Boolean*/autoDelete, /**Boolean*/internal,
        /**Boolean*/nowait, /**Object*/arguments){
    this.handler.call(Amqp.Class.Exchange, Amqp.Class.Exchange.Declare, args);
};
/**
 * Delete an exchange.
 *
 * This method deletes an exchange. When an exchange is deleted all queue bindings on the exchange
 * are cancelled.
 *
 * @param ticket An access ticket granted by the server for a certain set of access rights within a
 *      specific realm. Access tickets are valid within the channel where they were created, and
 *      expire when the channel closes.
 * @param exchange The exchange name is a client-selected string that identifies the exchange for
 *      publish methods. Exchange names may consist of any mixture of digits, letters, and
 *      underscores. Exchange names are scoped by the virtual host.
 * @param ifUnused If <code>true</code>, the server will only delete the exchange if it has no
 *      queue bindings. If the exchange has queue bindings the server does not delete it but raises
 *      a channel exception instead.
 * @param nowait If <code>true</code>, the server will not respond to the method. The client should
 *      not wait for a reply method. If the server could not complete the method it will raise a
 *      channel or connection exception.
 */
Exchange.prototype['delete'] = function(/**Number*/ticket, /**String*/exchange,
        /**Boolean*/ifUnused, /**Boolean*/nowait) {
    this.handler.call(Amqp.Class.Exchange, Amqp.Class.Exchange.Delete, { ticket: ticket,
        exchange: exchange, ifUnused: ifUnused, nowait: nowait });
}
exports.Exchange = Exchange;
